home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -serious- / misc / db3.6-beta / db3.6-beta-src / design.c < prev    next >
C/C++ Source or Header  |  1999-11-30  |  52KB  |  1,512 lines

  1.  
  2. #include <exec/types.h>
  3. #include <intuition/intuition.h>
  4. #include <libraries/gadtools.h>
  5. #include <proto/intuition.h>
  6. #include <proto/graphics.h>
  7. #include <proto/gadtools.h>
  8. #include <proto/utility.h>
  9. #include <proto/exec.h>                 /* CopyMem() */
  10. #include <string.h>             /* strcpy */
  11. #include <stdlib.h>     /* abs() macro */
  12.  
  13. #include "Design.h"
  14. #include "dbGUI.h"
  15. #include "dbparser.h"
  16. #include "Toolbox.h"
  17. #include "DesignGUI.h"
  18. #include "Version.h"
  19.  
  20. #include "Pointers.h"
  21.  
  22. #include <stdio.h> // Diagnostics
  23.  
  24. /*
  25.  * Externs to make the new GadToolsBox interface work
  26.  * Remove "static" from these in DesignGUI.c
  27.  */
  28. extern struct Gadget         *VisGadgets[];
  29. extern struct Window         *VisWnd;
  30. extern struct NewMenu                   DesignNewMenu[];
  31. extern struct Menu           *DesignMenus;
  32.  
  33. #define CURSORWIDTH 3
  34. #define DRAGTRESHOLD 6
  35. #define TOGGLE_LED *(UBYTE *)0xbfe001 ^= 2      /* Debug */
  36.  
  37. /* Handy macros */
  38. #define FLOOR(x,f) if ((x)<(f)) (x) = (f) 
  39.  
  40. /* Return codes from GadToolBox handlers */
  41. #define RET_OK 1
  42. #define RET_CANCEL 2
  43.  
  44.  
  45.  
  46. extern WORD LastLeftEdge;
  47. extern WORD LastTopEdge;                /* For nice layoutswitching */
  48.  
  49. extern void UpdateWindow(struct Pro *Pr);
  50. extern void UpdateDragBar(struct Pro *Pr);
  51.  
  52. typedef int Bool;       /* A char would be smaller, but will produce non-cast warnings */
  53.  
  54. typedef struct {
  55.         struct VisFldInfo *vf;
  56.         Bool after;     /* Has cursor passed field? (to the left or right of field) */
  57. } Cursor;
  58.  
  59.  
  60. struct EasyStruct ES_ViewDesignHelp =
  61. {
  62.         sizeof(struct EasyStruct),
  63.         0,
  64.         (STRPTR)"View design",
  65.         (STRPTR)"%s",
  66.         (STRPTR)"Ok"
  67. };
  68.  
  69.  
  70. /**********************************************************************/
  71. /*                              Globals                               */
  72. /**********************************************************************/
  73.  
  74. Cursor Crsr;
  75. struct VisFldInfo *Selected;    /* The selected field that has a rubberband */
  76. int DragCnt = 0;        /* Non-zero if dragging Selected. */
  77. Bool Sizing = FALSE;
  78.  
  79. struct Window *ToolBox = NULL;
  80.  
  81. /* GadToolBox handlers uses global variables */
  82. extern struct Pro *CurrentPro;
  83. struct VisFldInfo *Vf;
  84. extern char *RFFTagNames[];
  85.  
  86. /* The clipboard */
  87. struct VisFldInfo *Clip = NULL;
  88.  
  89. /**********************************************************************/
  90. /*                         Support functions                          */
  91. /**********************************************************************/
  92.  
  93. struct VisFldInfo *PrevVisFldInfo(struct Layout *Lay, struct VisFldInfo *vf)
  94. {
  95.         struct VisFldInfo *t = Lay->FirstVisFldInfo;
  96.         if (t == vf) return NULL;
  97.         for (; t; t = t->Next) if (t->Next == vf) return t;
  98.         return NULL; /* Safety */
  99. }
  100.  
  101. static void InitCursor(struct Layout *Lay, Cursor *crsr)
  102. {
  103.         crsr->vf = Lay->FirstVisFldInfo;
  104.         crsr->after = FALSE;
  105. }
  106.  
  107. static void GetCursorPosition(Cursor *crsr, WORD *x, WORD *y)
  108. {
  109.         /* Return position of cursor in (x,y) coords */
  110.         if (crsr->vf) {
  111.                 *y = crsr->vf->Pos.YOffset;
  112.                 *x = crsr->vf->Pos.XOffset;
  113.                 *x += (crsr->after) ? crsr->vf->Pos.Width + CURSORWIDTH : -2*CURSORWIDTH;
  114.         }
  115.         else {
  116.                 *x = OffX + FontX;                      /* As in CalcAllPos() */
  117.                 *y = OffY + (FontY >> 1);       /* As in CalcAllPos() */
  118.         }
  119. }
  120.  
  121. static int PreviousPosition(struct Layout *Lay, Cursor *crsr)
  122. {
  123.         /* Position cursor one step to the left (maybe up) */
  124.         /* Return FALSE if this is not possible */
  125.         struct VisFldInfo *vf;
  126.  
  127.         if (!crsr->vf) return FALSE;    /* No gadgets at all */
  128.  
  129.         if (crsr->after) {
  130.                 crsr->after = FALSE;
  131.                 return TRUE;
  132.         }
  133.         else if (vf = PrevVisFldInfo(Lay, crsr->vf)) {
  134.                 crsr->vf = vf;
  135.                 crsr->after = TRUE;
  136.                 return TRUE;
  137.         }
  138.         return FALSE;
  139. }
  140.  
  141. static int NextPosition(struct Layout *Lay, Cursor *crsr)
  142. {
  143.         /* Position cursor one step to the right (maybe down) */
  144.         /* Return FALSE if this is not possible */
  145.  
  146.         if (!crsr->vf) return FALSE;    /* No gadgets at all */
  147.  
  148.         if (!crsr->after) {
  149.                 crsr->after = TRUE;
  150.                 return TRUE;
  151.         }
  152.         else if (crsr->vf->Next) {
  153.                 crsr->vf = crsr->vf->Next;
  154.                 crsr->after = FALSE;
  155.                 return TRUE;
  156.  
  157.         }
  158.         return FALSE;
  159. }
  160.  
  161.  
  162. static void DisplayCursor(struct RastPort *rp, WORD x, WORD y)
  163. {
  164.         /* Draws a cursor in complement colour at given position */
  165.         /* Deletes cursor at old position automatically */
  166.         /* Specify a negative coordinate in either x or y to remove cursor */
  167.         /* DisplayCursor assumes a locked cursorheight */
  168.  
  169.         static WORD oldx = -1, oldy = -1;
  170.  
  171.         SetDrMd(rp, COMPLEMENT);
  172.  
  173.         if (oldx>=0 && oldy>=0)
  174.                 RectFill(rp, oldx, oldy, oldx+CURSORWIDTH-1, oldy+FontY+STRGADFRAMESHEIGHT-1);
  175.  
  176.         if (x>=0 && y>=0)
  177.                 RectFill(rp, x, y, x+CURSORWIDTH-1, y+FontY+STRGADFRAMESHEIGHT-1);
  178.         oldx = x;
  179.         oldy = y;
  180. }
  181.  
  182. static void Rubberband(struct RastPort *rp, WORD left, WORD top, WORD width, WORD height, char handle)
  183. {
  184.         /* Draws a border rectangle in complement colour. Adds a handle square if "handle" is TRUE */
  185.         /* Deletes old rubberband automatically */
  186.         /* Specify a negative coordinate in either left or top to remove rubberband */
  187.         static WORD oldleft = -1, oldtop = -1, oldwidth=-1, oldheight=-1, oldhandle = 0;
  188.  
  189.  
  190.         SetDrMd(rp, COMPLEMENT);
  191.         left--; top--; width++; height++;
  192.  
  193.         if (oldleft>=0 && oldtop>=0) {
  194.                 Move(rp, oldleft, oldtop);
  195.                 Draw(rp, oldleft+oldwidth, oldtop);
  196.                 Draw(rp, oldleft+oldwidth, oldtop+oldheight);
  197.                 Draw(rp, oldleft, oldtop+oldheight);
  198.                 Draw(rp, oldleft, oldtop);
  199.                 if (oldhandle) { /* Draw a 3x4 square in the middle of the right border */
  200.                         RectFill(rp, oldleft+oldwidth+1, oldtop+(oldheight>>1), oldleft+oldwidth+4, oldtop+(oldheight>>1)+2);
  201.                 }
  202.         }
  203.  
  204.         if (left>=0 && top>=0) {
  205.                 Move(rp, left, top);
  206.                 Draw(rp, left+width, top);
  207.                 Draw(rp, left+width, top+height);
  208.                 Draw(rp, left, top+height);
  209.                 Draw(rp, left, top);
  210.                 if (handle) { /* Draw a 3x4 square in the middle of the right border */
  211.                         RectFill(rp, left+width+1, top+(height>>1), left+width+4, top+(height>>1)+2);
  212.                 }
  213.         }
  214.         oldleft = left; oldtop = top; oldwidth = width; oldheight = height; oldhandle = handle;
  215.  
  216. }
  217.  
  218.  
  219. void FollowMouse(struct Layout *Lay, WORD mx, WORD my)
  220. {
  221.         /* Moves the cursor to the position that is nearest to (x,y) */
  222.         Cursor nearest;
  223.         WORD x,y;
  224.         WORD nx, ny;
  225.  
  226.         if (!Crsr.vf) return;
  227.         while (PreviousPosition(Lay, &Crsr));   /* Go to the beginning */
  228.         nearest = Crsr;
  229.         GetCursorPosition(&nearest, &nx, &ny);
  230.  
  231.         while (NextPosition(Lay, &Crsr)) {
  232.                 GetCursorPosition(&Crsr, &x, &y);
  233.                 if (abs(my-y) < abs(my-ny)) {
  234.                         nearest = Crsr;
  235.                         GetCursorPosition(&nearest, &nx, &ny);
  236.                 }
  237.                 if (abs(my-y) == abs(my-ny))
  238.                         if (abs(mx-x) < abs(mx-nx)) {
  239.                                 nearest = Crsr;
  240.                                 GetCursorPosition(&nearest, &nx, &ny);
  241.                         }
  242.         }
  243.         Crsr = nearest;
  244.         DisplayCursor(Lay->Window->RPort, nx, ny);
  245. }
  246.  
  247. static struct VisFldInfo *VisFldHit(struct Layout *Lay, WORD x, WORD y)
  248. {
  249.         /* Returns the address of the VisFldInfo that is hit by (x,y) */
  250.         struct VisFldInfo *vf = NULL;
  251.         
  252.         for (vf = Lay->FirstVisFldInfo; vf; vf = vf->Next) {
  253.                 if (x >= vf->Pos.XOffset && x < vf->Pos.XOffset+vf->Pos.Width &&
  254.                          y >= vf->Pos.YOffset && y < vf->Pos.YOffset+vf->Pos.Height)
  255.                          break;
  256.         }
  257.         return vf;
  258. }
  259.  
  260. static Bool SizeHit(struct VisFldInfo *hit, WORD mouseX)
  261. {
  262.         /* Return true if mouse is close to the right border of the "hit" field */
  263.         return (hit && (hit->Pos.XOffset + hit->Pos.Width - mouseX) < 5);
  264. }
  265.  
  266. void SelectVisFld(struct Layout *Lay, struct VisFldInfo *vf)
  267. {
  268.         if (Selected = vf) {
  269.                 struct Space *sp = &Selected->Pos;
  270.                 Rubberband(Lay->Window->RPort, sp->XOffset, sp->YOffset, sp->Width, sp->Height, 0);
  271.         }
  272.         else {
  273.                 Rubberband(Lay->Window->RPort, -1, -1, -1, -1, 0);
  274.         }
  275. }
  276.  
  277.  
  278. static struct VisFldInfo *RemoveVisFldInfo(struct Layout *Lay, struct VisFldInfo *oldvf)
  279. {
  280.         /* Remove oldvf from the layout and handle all side effects this may have */
  281.  
  282.         struct VisFldInfo *prev;
  283.  
  284.         if (!oldvf) return NULL;
  285.         prev = PrevVisFldInfo(Lay, oldvf);
  286.  
  287.         if (prev) {
  288.                 prev->Next = oldvf->Next;
  289.                 if (oldvf->VisSep == '\n' || oldvf->VisSep == '\f') {   /* end of line */
  290.                         prev->VisSep = oldvf->VisSep;
  291.                         WriteVisTags(prev);     /* Update RFF tags in vf */
  292.                 }
  293.         }
  294.         else Lay->FirstVisFldInfo = oldvf->Next;
  295.  
  296.         /* Handle cursor and rubberband */
  297.         if (Crsr.vf == oldvf) {
  298.                 if (Crsr.vf->Next) Crsr.vf = Crsr.vf->Next;
  299.                 else Crsr.vf = prev;    /* This might be NULL, and that's ok */
  300.         }
  301.         SelectVisFld(Lay, NULL);
  302.  
  303.         return oldvf;
  304. }
  305.  
  306.  
  307. static void InsertVisFldInfo(struct Layout *Lay, struct VisFldInfo *vf)
  308. {
  309.         /* Insert vf in the layout and handle all side effects this may have */
  310.         /* vf is placed at the cursor position */
  311.  
  312.         struct VisFldInfo **link_here;
  313.  
  314.         if (!Lay->FirstVisFldInfo) link_here = &Lay->FirstVisFldInfo;
  315.         else if (Crsr.after) {
  316.                 link_here = &Crsr.vf->Next;
  317.                 vf->VisSep = Crsr.vf->VisSep;
  318.                 Crsr.vf->VisSep = ' ';
  319.                 WriteVisTags(vf);
  320.                 WriteVisTags(Crsr.vf);
  321.         }
  322.         else {
  323.                 struct VisFldInfo *prevvf = PrevVisFldInfo(Lay, Crsr.vf);
  324.                 if (!prevvf) link_here = &Lay->FirstVisFldInfo;
  325.                 else link_here = &prevvf->Next;
  326.                 vf->VisSep = ' ';
  327.         }
  328.         /* Link */
  329.         vf->Next = *link_here;
  330.         *link_here = vf;
  331.  
  332. //      SelectVisFld(Lay, vf);          /* Now, it's easy to spot the new field */
  333. }
  334.  
  335. int DeleteUndo(struct Layout *Lay)
  336. {
  337.         struct VisFldInfo *vf,*nextvf;
  338.         for (vf = Lay->FirstUndoVisFldInfo; vf; vf=nextvf) {
  339.                 nextvf = vf->Next;
  340.                 DeleteVisFldInfo(vf);
  341.         }
  342.         Lay->FirstUndoVisFldInfo = NULL;
  343.         OffMenu(CurrentPro->CurrentLayout->Window, FULLMENUNUM(1,0,NOSUB)); /* Edit->Undo */
  344.         return 0;
  345. }
  346.  
  347. Bool PerformUndo(struct Layout *Lay)
  348. {
  349.         struct VisFldInfo *tmp;
  350.         if (!Lay->FirstUndoVisFldInfo) return FALSE;
  351.         tmp = Lay->FirstVisFldInfo;
  352.         Lay->FirstVisFldInfo = Lay->FirstUndoVisFldInfo;
  353.         Lay->FirstUndoVisFldInfo = tmp;
  354.         
  355.         Crsr.vf = Lay->FirstVisFldInfo;
  356.         Selected = NULL;
  357.         return TRUE;
  358. }
  359.  
  360. Bool SaveUndo(struct Layout *Lay)
  361. {
  362.         struct VisFldInfo *vf, **link_here;
  363.         DeleteUndo(Lay);        /* Remove old undo */
  364.         link_here = &Lay->FirstUndoVisFldInfo;
  365.         for (vf = Lay->FirstVisFldInfo; vf; vf=vf->Next, link_here = &((*link_here)->Next)) {
  366.                 if (!(*link_here = CopyVisFldInfo(vf))) return DeleteUndo(Lay);
  367.         }
  368.         OnMenu(CurrentPro->CurrentLayout->Window, FULLMENUNUM(1,0,NOSUB)); /* Edit->Undo */
  369.         CurrentPro->Modified |= PROMODIFIED;
  370.         return TRUE;
  371. }
  372.  
  373. static int Redraw(struct Pro *Pr, struct Layout *Lay)
  374. {
  375.         /* Recalculates all gadgets and redraws the updated window */
  376.         WORD ww, wh;
  377.         WORD x,y;
  378.         int ret;
  379.         Bool ok = TRUE;
  380.  
  381.         /* Tear down */
  382.         DisplayCursor(Lay->Window->RPort, -1, -1);
  383.         Rubberband(Lay->Window->RPort, -1, -1, -1, -1, 0);
  384.  
  385.         /* Rebuild with undo fallback */
  386.         do {
  387.                 if ((ret = CalcAllPos(Pr, Lay, &ww, &wh)) >= 0) {
  388.                         if ((ret = CreateAllGadgets(Pr, Lay, ww, wh, DESIGN_MODE)) >= 0) {
  389.                                 if ((ret = AttachAllGadgets(Lay, ww, wh, DESIGN_MODE)) >= 0) {
  390.  
  391.                                         DeleteAllGadgets(Lay, DESIGN_MODE);
  392.                                         GetCursorPosition(&Crsr, &x, &y);
  393.                                         DisplayCursor(Lay->Window->RPort, x, y);
  394.                                         SelectVisFld(Lay, Selected);    /* Update rubberband */
  395.  
  396.                                         /* Update pointer */
  397.                                         if (SizeHit(VisFldHit(Lay, DB_Msg.MouseX, DB_Msg.MouseY), DB_Msg.MouseX))
  398.                                                 ChangePointer(Lay->Window, LRPointer);
  399.                                         else RestorePointer(Lay->Window);
  400.                                         return ret;
  401.                                 }
  402.                         }
  403.                         DeleteAllGadgets(Lay, DESIGN_MODE);
  404.                 }
  405.                 DisplayBeep(Scr);
  406.                 ok = PerformUndo(Lay);
  407.                 DeleteUndo(Lay);
  408.         } while (ok);
  409.         return ret;             /* This is serious trouble */
  410. }
  411.  
  412.  
  413. int DoEdit(struct Pro *Pr, struct VisFldInfo *vf)
  414. {
  415.         /* Let the user perform the actual editing of a vf */
  416.         /* returns 0 if no changes has been made to vf */
  417.  
  418.         struct FldInfo *f;
  419.         BOOL quit = FALSE;
  420.         ULONG field_type = _STRING, new_field_type = _STRING;
  421.  
  422.         if (OpenVisWindow()) return 0;
  423.  
  424.         /* Prepare gadgets */
  425.         GT_SetGadgetAttrs(VisGadgets[GD_VIS_NAME], VisWnd, NULL,
  426.                 GTST_String, vf->Name, TAG_END);
  427.  
  428.         GT_SetGadgetAttrs(VisGadgets[GD_VIS_SIZE], VisWnd, NULL,
  429.                 GTIN_Number, vf->VisLen, TAG_END);
  430.  
  431.  
  432.         {
  433.         struct RFFTag *tag = FindTag(&vf->VisTags, FTYP);
  434.  
  435.         if(tag)
  436.            {
  437.            if(!stricmp(tag->Data, STR_TEXT))      field_type = _TEXT;
  438.            if(!stricmp(tag->Data, STR_CYCLE))     field_type = _CYCLE;
  439.            if(!stricmp(tag->Data, STR_CHECKBOX))  field_type = _CHECKBOX;
  440.            if(!stricmp(tag->Data, STR_TEXTFIELD)) field_type = _TEXTFIELD;
  441.            }
  442.         }
  443.         GT_SetGadgetAttrs(VisGadgets[GD_VIS_TYPE], VisWnd, NULL,
  444.                 GTCY_Active, field_type, TAG_END);
  445.  
  446.  
  447.         if (f = GetFldInfo(Pr, vf->Offset))
  448.                 GT_SetGadgetAttrs(VisGadgets[GD_VIS_FIELD], VisWnd, NULL,
  449.                         GTTX_Text, f->Name,
  450.                         TAG_END);
  451.         else GT_SetGadgetAttrs(VisGadgets[GD_VIS_FIELD], VisWnd, NULL,
  452.                         GTTX_Text, GetAppStr(MSG_EDVIEW_SELECT),
  453.                         TAG_END);
  454.  
  455.         Vf = vf;                /* GadTooBox handlers use global variables */
  456.  
  457.         /* Handle input */
  458.         while (!quit)
  459.            {
  460.                 WaitPort(VisWnd->UserPort);
  461.                 quit = HandleVisIDCMP();
  462.            }
  463.  
  464.         GT_GetGadgetAttrs(VisGadgets[GD_VIS_TYPE], VisWnd, NULL,
  465.               GTCY_Active, &new_field_type, TAG_END);
  466.  
  467.         CloseVisWindow();       /* GadToolBox automatically NULLs pointers */
  468.  
  469.         if (quit == RET_CANCEL) return 0;
  470.  
  471.         /* update vf */
  472.         strcpy(vf->Name, GetStringGadget(VisGadgets[GD_VIS_NAME]));
  473.         vf->VisLen = GetNumber(VisGadgets[GD_VIS_SIZE]);
  474.  
  475.         if(new_field_type != field_type)
  476.            {
  477.            struct RFFTag *tag;
  478.  
  479.            while(tag = FindTag(&vf->VisTags, CENT))
  480.                {
  481.                Remove((struct Node *)tag);
  482.                DeleteTag(tag);
  483.                }
  484.  
  485.            switch(new_field_type)
  486.                {
  487.                case _STRING:
  488.                    {
  489.                    struct RFFTag *tag;
  490.                    tag = FindTag(&vf->VisTags, FTYP);
  491.  
  492.                    if(tag)
  493.                       {
  494.                       Remove((struct Node *)tag);
  495.                       DeleteTag(tag);
  496.                       }
  497.                    }
  498.                    break;
  499.               case _TEXT:
  500.                    UpdateTag(&vf->VisTags, FTYP, STR_TEXT);
  501.                    break;
  502.               case _CHECKBOX:
  503.                    UpdateTag(&vf->VisTags, FTYP, STR_CHECKBOX);
  504.                    break;
  505.               case _TEXTFIELD:
  506.                    UpdateTag(&vf->VisTags, FTYP, STR_TEXTFIELD);
  507.                    break;
  508.               case _CYCLE:
  509.                    UpdateTag(&vf->VisTags, FTYP, STR_CYCLE);
  510.                    CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_1));
  511.                    CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_2));
  512.                    CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_3));
  513.                    break;
  514.               }
  515.           }
  516.  
  517.         WriteVisTags(vf);       /* Update RFF tags in vf */
  518.  
  519.         /* As user might have connected the vf to an internal field of cycle type,
  520.     * we must then remake the cycle list by reading the VisTags
  521.     */
  522.         if (ReadVisTags(Pr, vf) < 0) return 0;
  523.         /* vf->Offset and the tags has been updated inside GadToolBox */
  524.  
  525.         return 1;       /* Use */
  526. }
  527.  
  528. void ReplaceVisFldInfo(struct Layout *Lay, struct VisFldInfo *old, struct VisFldInfo *new)
  529. {
  530.         struct VisFldInfo *prev = PrevVisFldInfo(Lay, old);
  531.         new->Next = old->Next;
  532.         if (prev) prev->Next = new;
  533.         else Lay->FirstVisFldInfo = new;
  534.         
  535.         /* Don't forget to make sure that the cursor and rubberband points correctly */
  536.         if (Crsr.vf == old) Crsr.vf = new;
  537.         if (Selected == old) Selected = new;
  538. }
  539.  
  540.  
  541. static void EditVisFldInfo(struct Pro *Pr, struct Layout *Lay, struct VisFldInfo *vf)
  542. {
  543.         struct VisFldInfo *copy = CopyVisFldInfo(vf);
  544.         if (!copy) return;
  545.  
  546.         for (;;) {
  547.                 if (!DoEdit(Pr, copy)) {                /* Cancel */
  548.                         DeleteVisFldInfo(copy);
  549.                         Redraw(Pr, Lay);
  550.                         return;
  551.                 }
  552.                 else {
  553.                         ReplaceVisFldInfo(Lay, vf, copy);
  554.                         if (Redraw(Pr, Lay) < 0) {              /* Oops, this didn't fit on screen */
  555.                                 ReplaceVisFldInfo(Lay, copy, vf);
  556.                         }
  557.                         else break;
  558.                 }
  559.         }
  560.         DeleteVisFldInfo(vf);
  561. }
  562.  
  563. /**********************************************************************/
  564. /*                           Event handlers                           */
  565. /**********************************************************************/
  566.  
  567. static void CloseDesignWin(struct Layout *Lay)
  568. {
  569.         if (Lay->Window) {
  570.  
  571.                 DisplayCursor(Lay->Window->RPort, -1, -1);                              /* Remove cursor */
  572.                 Rubberband(Lay->Window->RPort, -1, -1, -1, -1, 0); /* Remove rubberband */
  573.  
  574.                 /* Remember old window pos */
  575.                 LastLeftEdge = Lay->Window->LeftEdge;
  576.                 LastTopEdge = Lay->Window->TopEdge;
  577.                 ClearMenuStrip(Lay->Window);
  578.                 FreeMenus( DesignMenus );
  579.                 DesignMenus = NULL;
  580.                 CloseWindow(Lay->Window);
  581.                 Lay->Window = NULL;
  582.         }
  583. }
  584.  
  585. static int RawKey(struct Pro *Pr, struct Layout *Lay)
  586. {
  587.         WORD x,y;
  588.         WORD oldx,oldy;
  589.         struct VisFldInfo *oldpos = Crsr.vf;
  590.  
  591.         switch (DB_Msg.Code) {
  592. /*              case RAW_F10:
  593.                         Redraw(Pr, Lay);
  594.                         return 0;
  595.                         break;  // Looks nice :-)
  596.  
  597.                 case RAW_F10-3:
  598.                         DeleteUndo(Lay);
  599.                         printf("DeleteUndo\n");
  600.                         break;
  601.  
  602.                 case RAW_F10-2:
  603.                         SaveUndo(Lay);
  604.                         printf("Save\n");
  605.                         break;
  606.  
  607.                 case RAW_F10-1:
  608.                         PerformUndo(Lay);
  609.                         Redraw(Pr, Lay);
  610.                         break;
  611. */
  612.  
  613.  
  614.                 case RAW_F1:
  615.                         ToolBoxClicked(Pr, Lay, StringID);
  616.                         break;
  617.                 case RAW_F2:
  618.                         ToolBoxClicked(Pr, Lay, TextID);
  619.                         break;
  620.                 case RAW_F3:
  621.                         ToolBoxClicked(Pr, Lay, TextFieldID);
  622.                         break;
  623.                 case RAW_F4:
  624.                         ToolBoxClicked(Pr, Lay, CycleID);
  625.                         break;
  626.                 case RAW_F5:
  627.                         ToolBoxClicked(Pr, Lay, CheckBoxID);
  628.                         break;
  629.  
  630.  
  631.  
  632.                 case RAW_HELP:
  633.                         EasyRequest(Lay->Window, &ES_ViewDesignHelp, NULL, GetAppStr(MSG_EDVIEW_HELP_BODY));
  634.  
  635.                         break;
  636.                 case RAW_LEFT:
  637.                         PreviousPosition(Lay, &Crsr);
  638.                         break;
  639.  
  640.                 case RAW_RIGHT:
  641.                         NextPosition(Lay, &Crsr);
  642.                         break;
  643.  
  644.                 case RAW_UP:
  645.                         GetCursorPosition(&Crsr, &oldx, &oldy);
  646.  
  647.                         while (PreviousPosition(Lay, &Crsr)) {
  648.                                 GetCursorPosition(&Crsr, &x, &y);
  649.                                 if (y < oldy && x <= oldx) break;
  650.                         }
  651.                         break;
  652.  
  653.                 case RAW_DOWN:
  654.                         GetCursorPosition(&Crsr, &oldx, &oldy);
  655.  
  656.                         while (NextPosition(Lay, &Crsr)) {
  657.                                 GetCursorPosition(&Crsr, &x, &y);
  658.                                 if (y > oldy) {
  659.                                         oldy = y;
  660.                                         break;
  661.                                 }
  662.                         }
  663.                         while (NextPosition(Lay, &Crsr)) {
  664.                                 GetCursorPosition(&Crsr, &x, &y);
  665.                                 if (y > oldy || x > oldx) {
  666.                                         PreviousPosition(Lay, &Crsr);
  667.                                         break;
  668.                                 }
  669.                         }
  670.                         break;
  671.         }
  672.         GetCursorPosition(&Crsr, &x, &y);
  673.         DisplayCursor(Lay->Window->RPort, x, y);
  674.         if (Crsr.vf != oldpos) SelectVisFld(Lay, NULL); /* Cursor has moved, so clear rubberband */
  675.         
  676.         return 0;
  677. }
  678.  
  679.  
  680. static int VanillaKey(struct Pro *Pr, struct Layout *Lay)
  681. {
  682.         struct VisFldInfo *vf = NULL;
  683.  
  684.         char oldVisSep;
  685.  
  686.         SaveUndo(Lay);
  687.         switch (DB_Msg.Code) {
  688.                 case '\r':
  689.                         if (Crsr.after) vf = Crsr.vf;
  690.                         else vf = PrevVisFldInfo(Lay, Crsr.vf);
  691.                         if (!vf) break;
  692.                         oldVisSep = vf->VisSep;
  693.                         switch (vf->VisSep) {
  694.                                 case ' ':
  695.                                 case '\t':
  696.                                         vf->VisSep = '\n';
  697.                                         break;
  698.                                 case '\n':
  699.                                         vf->VisSep = '\f';
  700.                                         break;
  701.                         }
  702.                         break;
  703.  
  704.                 case '\t':
  705.                         if (Crsr.after) vf = Crsr.vf;
  706.                         else vf = PrevVisFldInfo(Lay, Crsr.vf);
  707.                         if (!vf) break;
  708.                         oldVisSep = vf->VisSep;
  709.                         if (vf->VisSep == ' ') {
  710.                                 vf->VisSep = '\t';
  711.                         }
  712.                         break;
  713.                         
  714.                 case '\b':
  715.                         if (Crsr.after) break;
  716.                         else vf = PrevVisFldInfo(Lay, Crsr.vf);
  717.                         if (!vf) break;
  718.                         oldVisSep = vf->VisSep;
  719.                         switch (vf->VisSep) {
  720.                                 case '\t':
  721.                                 case '\n':
  722.                                         vf->VisSep = ' ';
  723.                                         break;
  724.                                 case '\f':
  725.                                         vf->VisSep = '\n';
  726.                                         break;
  727.                         }
  728.                         break;
  729.  
  730.                 case VANILLA_DEL:
  731.                         if (Selected) { /* Delete the selected field */
  732.                                 SaveUndo(Lay);
  733.                                 DeleteVisFldInfo(RemoveVisFldInfo(Lay, Selected));
  734.                                 Redraw(Pr, Lay);
  735.                                 return 0;
  736.                         }
  737.                         else {
  738.                                 if (!Crsr.after) break;
  739.                                 else vf = Crsr.vf;
  740.                                 if (!vf) break;
  741.                                 oldVisSep = vf->VisSep;
  742.                                 switch (vf->VisSep) {
  743.                                         case '\t':
  744.                                         case '\n':
  745.                                                 vf->VisSep = ' ';
  746.                                                 break;
  747.                                         case '\f':
  748.                                                 vf->VisSep = '\n';
  749.                                                 break;
  750.                                 }
  751.                         }
  752.                         break;
  753.  
  754.                 case VANILLA_ESC:
  755.                         return 1;       /* Exit design mode */
  756.                         break;
  757.         }
  758.  
  759.         if (vf && vf->VisSep != oldVisSep) {
  760.                 if (Redraw(Pr, Lay) < 0) {              /* Oops, this didn't fit on screen */
  761.                         DisplayBeep(Scr);
  762.                         vf->VisSep = oldVisSep;
  763.                         if (Redraw(Pr, Lay) < 0) ByeBye();              /* This should never happen */
  764.                 }
  765.                 WriteVisTags(vf);       /* Update RFF tags in vf */
  766.         }
  767.  
  768.         return 0;
  769. }
  770.  
  771.  
  772. int MouseButtons(struct Pro *Pr, struct Layout *Lay)
  773. {
  774.         static ULONG StartSeconds=0, StartMicros=0;
  775.         struct VisFldInfo *oldselected = Selected;
  776.  
  777.         if (Selected = VisFldHit(Lay, DB_Msg.MouseX, DB_Msg.MouseY)) {
  778.                 struct Space *sp = &Selected->Pos;
  779.                 Rubberband(Lay->Window->RPort, sp->XOffset, sp->YOffset, sp->Width, sp->Height, 0);
  780.  
  781.                 if (DoubleClick(StartSeconds, StartMicros, DB_Msg.Seconds, DB_Msg.Micros) &&
  782.                          Selected == oldselected) {
  783.                         if (DragCnt) {  /* Cancel dragging */
  784.                                 DragCnt = 0;
  785.                                 RestorePointer(Lay->Window);
  786.                         }
  787.                         EditVisFldInfo(Pr, Lay, Selected);
  788.                         StartSeconds = StartMicros = 0; /* Prevent "triple clicks" */
  789.                 }
  790.                 else {
  791.                         StartSeconds = DB_Msg.Seconds; StartMicros = DB_Msg.Micros;
  792.                         if (Selected) {
  793.                                 if (SizeHit(Selected, DB_Msg.MouseX)) {
  794.                                         Sizing = TRUE;
  795.                                         Forbid();
  796.                                         Lay->Window->Flags |= WFLG_RMBTRAP;
  797.                                         Permit();
  798.                                 }
  799.                                 else DragCnt = 1; /* Initiate dragging */
  800.                         }
  801.                 }
  802.         }
  803.         else {
  804.                 Rubberband(Lay->Window->RPort, -1, -1, -1, -1, 0);
  805.                 FollowMouse(Lay, DB_Msg.MouseX, DB_Msg.MouseY);
  806.         }
  807.         return 0;
  808. }
  809.  
  810.  
  811. static void ToolBoxClicked(struct Pro *Pr, struct Layout *Lay, int gadgetID)
  812. {
  813.         struct VisFldInfo *vf;
  814.  
  815.         /* Make a VisFldInfo */
  816.         if (!(vf = NewVisFldInfo())) return;
  817.         
  818.         /* Fill in type (string, cycle, checkbox, textfield or text) */
  819.         switch (gadgetID) {
  820.                 case CheckBoxID:
  821.                         CreateAndAddTag(&vf->VisTags, FTYP, STR_CHECKBOX);
  822.                         vf->VisLen = 3; /* smaller is better */
  823.                         break;
  824.                 case TextID:
  825.                         CreateAndAddTag(&vf->VisTags, FTYP, STR_TEXT);
  826.                         vf->VisLen = 10;
  827.                         break;
  828.                 case TextFieldID:
  829.                         if(TextFieldClass)
  830.                             {
  831.                             CreateAndAddTag(&vf->VisTags, FTYP, STR_TEXTFIELD);
  832.                             CreateAndAddTag(&vf->VisTags, ROWS, "4");
  833.                             vf->VisLen = 15;
  834.                             }
  835.                         break;
  836.                 case CycleID:
  837.                         CreateAndAddTag(&vf->VisTags, FTYP, STR_CYCLE);
  838.                         CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_1));
  839.                         CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_2));
  840.                         CreateAndAddTag(&vf->VisTags, CENT, GetAppStr(MSG_EDVIEW_CYCLE_3));
  841.                         vf->VisLen = 16;        /* smaller is better */
  842.                         break;
  843.         }
  844.         ReadVisTags(Pr, vf);    /* This way we get the cycle-list in vf */
  845.         vf->Name[0] = '\0'; 
  846.  
  847.         /* Release the user */
  848.         if (!DoEdit(Pr, vf)) {  /* Cancel */
  849.                 DeleteVisFldInfo(vf);
  850.                 return;
  851.         }
  852.  
  853.         InsertVisFldInfo(Lay, vf);              /* link it */
  854.  
  855.         if (Redraw(Pr, Lay) < 0) {              /* Oops, this didn't fit on screen */
  856.                 DisplayBeep(Scr);
  857.                 DeleteVisFldInfo(RemoveVisFldInfo(Lay, vf));
  858.                 Redraw(Pr, Lay);
  859.         }
  860.         if (!Crsr.vf) Crsr.vf = Lay->FirstVisFldInfo;   /* Move cursor on-track */
  861. }
  862.  
  863. /**********************************************************************/
  864. /*                           IDCMP handler                            */
  865. /**********************************************************************/
  866.  
  867. static int DesignWindowIDCMP(struct Pro *Pr, struct Layout *Lay)
  868. {
  869.         struct IntuiMessage     *m;
  870.         struct MenuItem         *n;
  871.         int                     (*func)(void);
  872.         struct Window *Win = Lay->Window;
  873.         ULONG signals, winsig, toolboxsig = 0;
  874.         BOOL running = TRUE;
  875.  
  876.         winsig = 1L << Win->UserPort->mp_SigBit;
  877.         if (ToolBox) toolboxsig = 1L << ToolBox->UserPort->mp_SigBit;
  878.  
  879.         for (;;) {
  880. //              WaitPort(Win->UserPort);
  881.                 signals = Wait(winsig | toolboxsig);
  882.  
  883.                 if (signals & winsig) {
  884.                         while( m = GT_GetIMsg( Win->UserPort )) {
  885.  
  886.                                 CopyMem(( char * )m, ( char * )&DB_Msg, (long)sizeof( struct IntuiMessage ));
  887.  
  888.                                 GT_ReplyIMsg( m );
  889.                                 
  890.                                 switch ( DB_Msg.Class ) {
  891.                                 
  892.                                         case    IDCMP_REFRESHWINDOW:
  893.                                                 GT_BeginRefresh(Win);
  894.                                                 GT_EndRefresh(Win, TRUE );
  895.                                                 break;
  896.  
  897.                                         case    IDCMP_CLOSEWINDOW:
  898.                                                 return 0;
  899.                                                 break;
  900.  
  901.                                         case    IDCMP_NEWSIZE:
  902. //      //                                      printf("IDCMP_NEWSIZE\n");
  903.                                                 if (!(Win->Flags & WFLG_ZOOMED)) Redraw(Pr, Lay);
  904.                                                 break;
  905.  
  906.                                         case    IDCMP_VANILLAKEY:
  907. //      //                                      printf("IDCMP_VANILLAKEY\n");
  908.                                                 running = VanillaKey(Pr, Lay);
  909.                                                 if (running) return running;
  910.                                                 break;
  911.  
  912.                                         case    IDCMP_RAWKEY:
  913. //      //                                      printf("IDCMP_RAWKEY\n");
  914.                                                 running = RawKey(Pr, Lay);
  915.                                                 break;
  916.  
  917.                                         case    IDCMP_MOUSEMOVE:
  918.                                                 {
  919.                                                         if (Sizing) {
  920.                                                                 Selected->Pos.Width = DB_Msg.MouseX - Selected->Pos.XOffset;
  921.                                                                 FLOOR(Selected->Pos.Width, FontX+STRGADFRAMESWIDTH);
  922.                                                                 SelectVisFld(Lay, Selected);    /* Update rubberband */
  923.                                                                 break;
  924.                                                         }
  925.                                                         else if (DragCnt) {
  926.                                                                 if (DragCnt++ == DRAGTRESHOLD) {
  927.                                                                         ChangePointer(Win, MovePointer);
  928.                                                                         Forbid();
  929.                                                                         Win->Flags |= WFLG_RMBTRAP;
  930.                                                                         Permit();
  931.                                                                 }
  932.                                                                 FollowMouse(Lay, DB_Msg.MouseX, DB_Msg.MouseY);
  933.                                                         }
  934.                                                         else if (SizeHit(VisFldHit(Lay, DB_Msg.MouseX, DB_Msg.MouseY), DB_Msg.MouseX))
  935.                                                                 ChangePointer(Win, LRPointer);
  936.                                                         else RestorePointer(Win);
  937.                                                 }
  938. //                                              printf("IDCMP_MOUSEMOVE\n");
  939.                                                 break;
  940.  
  941.                                         case IDCMP_MOUSEBUTTONS:
  942.                                                 if (DB_Msg.Code == SELECTDOWN) {
  943.                                                         running = MouseButtons(Pr, Lay);
  944.                                                 }
  945.                                                 else if (DB_Msg.Code == SELECTUP) {
  946.                                                         if (Win->Flags & WFLG_RMBTRAP) {        /* Enable menu button again */
  947.                                                                 Forbid();
  948.                                                                 Win->Flags &= ~WFLG_RMBTRAP;
  949.                                                                 Permit();
  950.                                                         }
  951.                                                         if (DragCnt >= DRAGTRESHOLD) {
  952.                                                                 RestorePointer(Win);
  953.                                                                 if (Crsr.vf != Selected) {              /* Move it */
  954.                                                                         SaveUndo(Lay);
  955.                                                                         InsertVisFldInfo(Lay, RemoveVisFldInfo(Lay, Selected));
  956.                                                                         Redraw(Pr, Lay);
  957.                                                                 }
  958.                                                         }
  959.                                                         else if (Sizing) {
  960.                                                                 Sizing = FALSE;
  961.                                                                 SaveUndo(Lay);
  962.                                                                 Selected->VisLen = (Selected->Pos.Width+(FontX+1)/2-STRGADFRAMESWIDTH)/FontX;
  963.                                                                 WriteVisTags(Selected); /* Update RFF tags in vf */
  964.                                                                 Redraw(Pr, Lay);
  965.                                                         }
  966.                                                         DragCnt = 0;
  967.                                                 }
  968.                                                 else if (DB_Msg.Code == MENUUP) { /* Cancel */
  969.                                                         if (Win->Flags & WFLG_RMBTRAP) {        /* Enable menu button again */
  970.                                                                 Forbid();
  971.                                                                 Win->Flags &= ~WFLG_RMBTRAP;
  972.                                                                 Permit();
  973.                                                         }
  974.  
  975.                                                         if (DragCnt) {  /* Cancel dragging */
  976.                                                                 DragCnt = 0;
  977.                                                                 RestorePointer(Win);
  978.                                                         }
  979.                                                         else if (Sizing) {      /* Cancel sizechange */
  980.                                                                 Sizing = FALSE;
  981.                                                                 Redraw(Pr, Lay);
  982.                                                         }
  983.                                                 }
  984.                                                 break;
  985.                                                 
  986.                                         case IDCMP_MENUPICK:
  987.                                                 while( DB_Msg.Code != MENUNULL ) {
  988.                                                         n = ItemAddress( Win->MenuStrip, DB_Msg.Code );
  989.                                                         func = (int (*)(void))(GTMENUITEM_USERDATA( n ));
  990.                                                         running = func();
  991.                                                         if (running) return running;    /* The window has been closed! */
  992.                                                         DB_Msg.Code = n->NextSelect;
  993.                                                 }
  994.                                                 break;
  995.                                 }
  996.                         }
  997.                 }       /* winsig signals */
  998.  
  999.                 if (signals & toolboxsig) {
  1000.                         while( m = GT_GetIMsg( ToolBox->UserPort )) {
  1001.  
  1002.                                 CopyMem(( char * )m, ( char * )&DB_Msg, (long)sizeof( struct IntuiMessage ));
  1003.  
  1004.                                 GT_ReplyIMsg( m );
  1005.                                 
  1006.                                 switch ( DB_Msg.Class ) {
  1007.                                         case IDCMP_GADGETUP:
  1008. //                                              printf("Gadget up\n");
  1009.                                                 ActivateWindow(Win);
  1010.                                                 ToolBoxClicked(Pr, Lay, ((struct Gadget *)DB_Msg.IAddress)->GadgetID);
  1011.                                                 break;
  1012.                                 }
  1013.                         }
  1014.                 } /* toolbox signals */
  1015.         }
  1016.  
  1017.  
  1018.         return( running );
  1019. }
  1020.  
  1021.  
  1022. char TitleBuffer[80];
  1023.  
  1024. static int DoOpenDesignWindow(struct Pro *Pr, struct Layout *Lay, WORD ww, WORD wh)
  1025. {
  1026.  
  1027.         /* Does the actual opening (in DESIGN_MODE) */
  1028.         WORD leftedge, topedge;
  1029.  
  1030.         /* Position window nicely */
  1031.         if (LastLeftEdge == -1) {       /* No previous window to use */
  1032.                 leftedge = (Scr->Width - ww) >> 1;      /* Middle */
  1033.                 topedge = (Scr->Height-wh) >> 1;                /* Middle */
  1034.         }
  1035.         else {
  1036.                 leftedge = LastLeftEdge;
  1037.                 topedge = LastTopEdge;
  1038.         }
  1039.  
  1040.         /* We create this menu every time we enter view design */
  1041.         if ( ! ( DesignMenus = CreateMenus( DesignNewMenu, TAG_DONE )))
  1042.                 return( 3L );
  1043.  
  1044.         LayoutMenus( DesignMenus, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE );
  1045.  
  1046.  
  1047.         /* Localization. Not optimal, but works ;-) */
  1048.         ES_ViewDesignHelp.es_Title = GetAppStr(MSG_EDVIEW_HELP_TITLE);
  1049.         ES_ViewDesignHelp.es_GadgetFormat = GetAppStr(MSG_REQ_OK);
  1050.         sprintf(TitleBuffer, GetAppStr(MSG_EDVIEW_SCR_TITLE), VERSION_NUMBER);
  1051.  
  1052.         if ( ! ( Lay->Window = OpenWindowTags( NULL,
  1053.                                 WA_Left,           leftedge,
  1054.                                 WA_Top,         topedge,
  1055.                                 WA_Width,       ww,
  1056.                                 WA_Height,      wh,
  1057.                                 WA_IDCMP,       IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_NEWSIZE|IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_RAWKEY|IDCMP_VANILLAKEY|IDCMP_REFRESHWINDOW,
  1058.                                 WA_Flags,       WFLG_REPORTMOUSE|WFLG_NEWLOOKMENUS|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE,
  1059.                                 WA_Gadgets,     Lay->GList,
  1060.                                 WA_Title,       GetAppStr(MSG_EDVIEW_WIN_TITLE),
  1061.                                 WA_ScreenTitle, TitleBuffer,
  1062.                                 WA_PubScreen,   Scr,
  1063.                                 WA_Zoom,        DB_Zoom,
  1064. //                              WA_MenuHelp, TRUE,
  1065.                                 TAG_DONE )))
  1066.         return WIN_ERR;
  1067.  
  1068.         SetMenuStrip( Lay->Window, DesignMenus );
  1069.         GT_RefreshWindow( Lay->Window, NULL);
  1070.  
  1071.         /* Now detach all gadgets from the window as this is the design mode */
  1072.         RemoveGList(Lay->Window, Lay->GList, -1);
  1073.  
  1074.         /* We delete the gadgets and just leave the imagery */
  1075.         DeleteAllGadgets(Lay, DESIGN_MODE);
  1076.  
  1077.         /* For IDCMP handling used in this file */
  1078.         WinSig = 1L << Lay->Window->UserPort->mp_SigBit;
  1079.  
  1080.         return 0;
  1081. }
  1082.  
  1083. void FillClip(struct VisFldInfo *vf)
  1084. {
  1085.         if (Clip) {
  1086.                 DeleteVisFldInfo(Clip);
  1087.         }
  1088.         Clip = vf;
  1089. }
  1090.  
  1091. /**********************************************************************/
  1092. /*                        Interface functions                         */
  1093. /**********************************************************************/
  1094.  
  1095. void Design(struct Pro *Pr, struct Layout *Lay)
  1096. {
  1097.         /* This is the main function in the design system */
  1098.         WORD ww, wh;
  1099.         WORD x,y;
  1100.  
  1101. /*      ww = Lay->Window->Width;
  1102.         wh = Lay->Window->Height;
  1103. */
  1104.         CloseLayWin(Pr, Lay);
  1105.         CalcAllPos(Pr, Lay, &ww, &wh); // Shouldn't be nessesary as we reopen the window
  1106.         CreateAllGadgets(Pr, Lay, ww, wh, DESIGN_MODE);
  1107.         DoOpenDesignWindow(Pr, Lay, ww, wh);
  1108.  
  1109.         InitCursor(Lay, &Crsr);
  1110.         Selected = NULL;
  1111.         GetCursorPosition(&Crsr, &x, &y);
  1112.         DisplayCursor(Lay->Window->RPort, x, y);
  1113.  
  1114.         ToolBox = OpenToolBox(Lay->Window);     /* "Parent" window */
  1115.  
  1116.         DesignWindowIDCMP(Pr, Lay);
  1117.  
  1118.         DeleteUndo(Lay);
  1119.         FillClip(NULL);
  1120.  
  1121.         CloseDesignWin(Lay);
  1122.         if (ToolBox) {
  1123.                 CloseToolBox(ToolBox);
  1124.                 ToolBox = NULL;
  1125.         }
  1126.         OpenLayWin(Pr, Lay);
  1127.         UpdateWindow(Pr);
  1128.         UpdateDragBar(Pr);
  1129.  
  1130.         /* Back to db run-mode */
  1131. }
  1132.  
  1133.  
  1134.  
  1135. /**********************************************************************/
  1136. /*                        GadToolBox handlers                         */
  1137. /**********************************************************************/
  1138.  
  1139.  
  1140. int LISTClicked( void )
  1141. {
  1142.         /* routine when gadget "Object list" is clicked. */
  1143.         return 0;
  1144. }
  1145.  
  1146. int TOPClicked( void )
  1147. {
  1148.         /* routine when gadget "Top" is clicked. */
  1149.         return 0;
  1150. }
  1151.  
  1152. int UPClicked( void )
  1153. {
  1154.         /* routine when gadget "Up" is clicked. */
  1155.         return 0;
  1156. }
  1157.  
  1158. int DOWNClicked( void )
  1159. {
  1160.         /* routine when gadget "Down" is clicked. */
  1161.         return 0;
  1162. }
  1163.  
  1164. int BOTTOMClicked( void )
  1165. {
  1166.         /* routine when gadget "Bottom" is clicked. */
  1167.         return 0;
  1168. }
  1169.  
  1170. int NEWClicked( void )
  1171. {
  1172.         /* routine when gadget "_New..." is clicked. */
  1173.         return 0;
  1174. }
  1175.  
  1176. int EDITClicked( void )
  1177. {
  1178.         /* routine when gadget "_Edit..." is clicked. */
  1179.         return 0;
  1180. }
  1181.  
  1182. int COPYClicked( void )
  1183. {
  1184.         /* routine when gadget "Co_py" is clicked. */
  1185.         return 0;
  1186. }
  1187.  
  1188. int REMOVEClicked( void )
  1189. {
  1190.         /* routine when gadget "Remove" is clicked. */
  1191.         return 0;
  1192. }
  1193.  
  1194. int USEClicked( void )
  1195. {
  1196.         /* routine when gadget "_Use" is clicked. */
  1197.         return 0;
  1198. }
  1199.  
  1200. int CANCELClicked( void )
  1201. {
  1202.         /* routine when gadget "_Cancel" is clicked. */
  1203.         return 0;
  1204. }
  1205.  
  1206. int TAG_VALUEClicked( void )
  1207. {
  1208.         /* routine when gadget "_Value" is clicked. */
  1209.         return 0;
  1210. }
  1211.  
  1212. int TAG_IDClicked( void )
  1213. {
  1214.         /* routine when gadget "_ID" is clicked. */
  1215.         return 0;
  1216. }
  1217.  
  1218. int TAG_OKClicked( void )
  1219. {
  1220.         /* routine when gadget "_Ok" is clicked. */
  1221.         return 0;
  1222. }
  1223.  
  1224. int TAG_CANCELClicked( void )
  1225. {
  1226.         /* routine when gadget "_Cancel" is clicked. */
  1227.         return 0;
  1228. }
  1229.  
  1230. int NAME_NAMEClicked( void )
  1231. {
  1232.         /* routine when gadget "_Name" is clicked. */
  1233.         return 0;
  1234. }
  1235.  
  1236. int NAME_OKClicked( void )
  1237. {
  1238.         /* routine when gadget "_Ok" is clicked. */
  1239.         return 0;
  1240. }
  1241.  
  1242. int NAME_CANCELClicked( void )
  1243. {
  1244.         /* routine when gadget "_Cancel" is clicked. */
  1245.         return 0;
  1246. }
  1247.  
  1248. int FIELD_NAMEClicked( void )
  1249. {
  1250.         /* routine when gadget "_Name" is clicked. */
  1251.         return 0;
  1252. }
  1253.  
  1254. int FIELD_MAXLENClicked( void )
  1255. {
  1256.         /* routine when gadget "Max _length" is clicked. */
  1257.         return 0;
  1258. }
  1259.  
  1260. int FIELD_OKClicked( void )
  1261. {
  1262.         /* routine when gadget "_Ok" is clicked. */
  1263.         return 0;
  1264. }
  1265.  
  1266. int FIELD_CANCELClicked( void )
  1267. {
  1268.         /* routine when gadget "_Cancel" is clicked. */
  1269.         return 0;
  1270. }
  1271.  
  1272. int FIELD_MOREClicked( void )
  1273. {
  1274.         /* routine when gadget "_More..." is clicked. */
  1275.         return 0;
  1276. }
  1277.  
  1278. int VIS_NAMEClicked( void )
  1279. {
  1280.         /* routine when gadget "_Name" is clicked. */
  1281.         return 0;
  1282. }
  1283.  
  1284. int VIS_SIZEClicked( void )
  1285. {
  1286.         /* routine when gadget "Si_ze" is clicked. */
  1287.         return 0;
  1288. }
  1289.  
  1290. int VIS_OKClicked( void )
  1291. {
  1292.         /* routine when gadget "_Ok" is clicked. */
  1293.         return RET_OK;
  1294. }
  1295.  
  1296. int VIS_CANCELClicked( void )
  1297. {
  1298.         /* routine when gadget "_Cancel" is clicked. */
  1299.         return RET_CANCEL;
  1300. }
  1301.  
  1302. int VIS_MOREClicked( void )
  1303. {
  1304.         /* routine when gadget "_More..." is clicked. */
  1305.         return 0;
  1306. }
  1307.  
  1308. int VIS_SELECTClicked( void )
  1309. {
  1310.         /* routine when gadget "..." is clicked. */
  1311.         Select *s;
  1312.         struct FldInfo *f;
  1313.         BOOL again = TRUE;
  1314.  
  1315.  
  1316.         if (!(s = NewSelect())) {
  1317.                 DisplayBeep(Scr);
  1318.                 return 0;
  1319.         }
  1320.         for (f = CurrentPro->FirstFldInfo; f; f = f->Next)
  1321.                 AddStringLast(s, f->Name);
  1322.  
  1323.         s->SelIndex = Vf->Offset;
  1324.         OpenSelect(s, VisWnd, GetAppStr(MSG_EDVIEW_WIN_SELECT_TITLE), NULL);
  1325.         while (again) {
  1326.                 WaitPort(s->SelWnd->UserPort);
  1327.                 switch(HandleSelectIDCMP(s)) {
  1328.                         case SEL_SELECT :
  1329.                                 break;
  1330.                         case SEL_OK :
  1331.                                 Vf->Offset = s->SelIndex;
  1332.                                 GT_SetGadgetAttrs(VisGadgets[GD_VIS_FIELD], VisWnd, NULL,
  1333.                                         GTTX_Text, SelectedString(s),
  1334.                                         TAG_END);
  1335.                                 again = FALSE;
  1336.                                 break;
  1337.                         case SEL_CANCEL :
  1338.                                 again = FALSE;
  1339.                                 break;
  1340.                         case SEL_HELP :
  1341.                                 break;
  1342.                 }
  1343.         }
  1344.  
  1345. /*
  1346.         CloseSelect(s);
  1347.         RemoveAllStrings(s);
  1348. */
  1349.         DeleteSelect(s);
  1350.  
  1351.         return 0;
  1352. }
  1353.  
  1354. int MainCloseWindow( void )
  1355. {
  1356.         /* routine for "IDCMP_CLOSEWINDOW". */
  1357.         return 1;       /* i.e. Leave this mode */
  1358. }
  1359.  
  1360. int MainVanillaKey( void )
  1361. {
  1362.         /* routine for "IDCMP_VANILLAKEY". */
  1363.         return 0;
  1364. }
  1365.  
  1366. int MainRawKey( void )
  1367. {
  1368.         /* routine for "IDCMP_RAWKEY". */
  1369.         return 0;
  1370. }
  1371.  
  1372. int TagCloseWindow( void )
  1373. {
  1374.         /* routine for "IDCMP_CLOSEWINDOW". */
  1375.         return 0;
  1376. }
  1377.  
  1378. int TagVanillaKey( void )
  1379. {
  1380.         /* routine for "IDCMP_VANILLAKEY". */
  1381.         return 0;
  1382. }
  1383.  
  1384. int NameCloseWindow( void )
  1385. {
  1386.         /* routine for "IDCMP_CLOSEWINDOW". */
  1387.         return 0;
  1388. }
  1389.  
  1390. int NameVanillaKey( void )
  1391. {
  1392.         /* routine for "IDCMP_VANILLAKEY". */
  1393.         return 0;
  1394. }
  1395.  
  1396. int FieldCloseWindow( void )
  1397. {
  1398.         /* routine for "IDCMP_CLOSEWINDOW". */
  1399.         return 0;
  1400. }
  1401.  
  1402. int FieldVanillaKey( void )
  1403. {
  1404.         /* routine for "IDCMP_VANILLAKEY". */
  1405.         return 0;
  1406. }
  1407.  
  1408. int VisCloseWindow( void )
  1409. {
  1410.         /* routine for "IDCMP_CLOSEWINDOW". */
  1411.         return RET_CANCEL;
  1412. }
  1413.  
  1414. int VisVanillaKey( void )
  1415. {
  1416.         /* routine for "IDCMP_VANILLAKEY". */
  1417.  
  1418.         switch (ToUpper(VisMsg.Code)) {
  1419.         case 'N':
  1420.                 ActivateGadget(VisGadgets[GD_VIS_NAME], VisWnd, NULL);
  1421.                 break;
  1422.  
  1423.         case 'Z':
  1424.                 ActivateGadget(VisGadgets[GD_VIS_SIZE], VisWnd, NULL);
  1425.                 break;
  1426.  
  1427.         case 'T':
  1428.                 {
  1429.                 ULONG active;
  1430.  
  1431.                 if(GT_GetGadgetAttrs(VisGadgets[GD_VIS_TYPE], VisWnd, NULL,
  1432.                                    GTCY_Active, &active, TAG_END) == 1)
  1433.                     {
  1434.                     active = (active + 1) % 5;
  1435.  
  1436.                     GT_SetGadgetAttrs(VisGadgets[GD_VIS_TYPE], VisWnd, NULL,
  1437.                                    GTCY_Active, active, TAG_END);
  1438.                     }
  1439.                 }
  1440.                 break;
  1441.  
  1442.         case 'O':
  1443.         case '\r':
  1444.                 return VIS_OKClicked();
  1445.                 break;
  1446.                 
  1447.         case 'C':
  1448.         case VANILLA_ESC:
  1449.                 return VIS_CANCELClicked();
  1450.                 break;
  1451.         }
  1452.         return 0;
  1453. }
  1454.  
  1455. int DesignPROJECT_ABOUT( void )
  1456. {
  1457.         /* routine when (sub)item "About view design..." is selected. */
  1458.         EasyRequest(CurrentPro->CurrentLayout->Window, &ES_ViewDesignHelp, NULL, GetAppStr(MSG_EDVIEW_HELP_BODY));
  1459.  
  1460.         return 0;
  1461. }
  1462.  
  1463. int DesignPROJECT_EXIT( void )
  1464. {
  1465.         /* routine when (sub)item "Exit view design" is selected. */
  1466.         return 1;       /* Leave View design */
  1467. }
  1468.  
  1469. int DesignEDIT_UNDO( void )
  1470. {
  1471.         /* routine when (sub)item "Undo" is selected. */
  1472.  
  1473.         if (PerformUndo(CurrentPro->CurrentLayout))
  1474.                 Redraw(CurrentPro, CurrentPro->CurrentLayout);
  1475.         else DisplayBeep(Scr);
  1476.         return 0;
  1477. }
  1478.  
  1479. int DesignEDIT_CUT( void )
  1480. {
  1481.         /* routine when (sub)item "Cut" is selected. */
  1482.  
  1483.         if (Selected) {
  1484.                 SaveUndo(CurrentPro->CurrentLayout);
  1485.                 FillClip(RemoveVisFldInfo(CurrentPro->CurrentLayout, Selected));
  1486.                 OnMenu(CurrentPro->CurrentLayout->Window, FULLMENUNUM(1,4,NOSUB)); /* Edit->Paste */
  1487.                 Redraw(CurrentPro, CurrentPro->CurrentLayout);
  1488.         }
  1489.         return 0;
  1490. }
  1491.  
  1492. int DesignEDIT_COPY( void )
  1493. {
  1494.         /* routine when (sub)item "Copy" is selected. */
  1495.  
  1496.         if (Selected) {
  1497.                 FillClip(CopyVisFldInfo(Selected));
  1498.                 OnMenu(CurrentPro->CurrentLayout->Window, FULLMENUNUM(1,4,NOSUB)); /* Edit->Paste */
  1499.         }
  1500.         return 0;
  1501. }
  1502.  
  1503. int DesignEDIT_PASTE( void )
  1504. {
  1505.         /* routine when (sub)item "Paste" is selected. */
  1506.  
  1507.         SaveUndo(CurrentPro->CurrentLayout);
  1508.         InsertVisFldInfo(CurrentPro->CurrentLayout, CopyVisFldInfo(Clip));
  1509.         Redraw(CurrentPro, CurrentPro->CurrentLayout);
  1510.         return 0;
  1511. }
  1512.